Conditions | 1 |
Paths | 128 |
Total Lines | 289 |
Code Lines | 157 |
Lines | 0 |
Ratio | 0 % |
Changes | 5 | ||
Bugs | 3 | Features | 3 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
1 | /* |
||
8 | $.fn.formJS = function ( options ) { |
||
9 | var obj = this; |
||
10 | |||
11 | var settings = $.extend( true, { |
||
12 | alerts: { |
||
13 | unexpected: { |
||
14 | title: 'Error', |
||
15 | message: 'Unexpected error occurred' |
||
16 | }, |
||
17 | failSend: { |
||
18 | title: 'Error', |
||
19 | message: 'Unable to send data' |
||
20 | } |
||
21 | }, |
||
22 | keys: { |
||
23 | success: 'success', |
||
24 | info: 'info', |
||
25 | warning: 'warning', |
||
26 | error: 'error' |
||
27 | }, |
||
28 | icons: { |
||
29 | loading: '<span>⌛</span>', |
||
30 | success: '<span>✓</span>', |
||
31 | info: '<span>🛈</span>', |
||
32 | warning: '<span>﹗</span>', |
||
33 | error: '<span>⨯</span>' |
||
34 | }, |
||
35 | form: { |
||
36 | ajaxSettings: { |
||
37 | contentType: false |
||
38 | }, |
||
39 | alertContainer: '.formJS', |
||
40 | btnSubmit: '.btn[type="submit"]', |
||
41 | enableWriteAlert: true |
||
42 | }, |
||
43 | redirection: { |
||
44 | message: 'Automatic redirection in a second', |
||
45 | delay: 1100 |
||
46 | }, |
||
47 | callback: function ( currentAlert ) { |
||
|
|||
48 | } |
||
49 | }, options ); |
||
50 | |||
51 | return obj.each( function () { |
||
52 | var $this = $( this ); |
||
53 | var action = $this.attr( "action" ); |
||
54 | var method = $this.attr( "method" ); |
||
55 | var btnSubmit = $this.find( settings.form.btnSubmit ); |
||
56 | var currentAlert = $.extend( settings.alerts.unexpected, { type: 'error' } ); |
||
57 | var ajaxPending = false; |
||
58 | var ajaxSettings; |
||
59 | var formdata; |
||
60 | var data; |
||
61 | |||
62 | /** |
||
63 | * Sending data method |
||
64 | * @param e |
||
65 | */ |
||
66 | $this.sendData = function ( e ) { |
||
67 | e.preventDefault(); |
||
68 | |||
69 | // --------------- Check if an ajax request is in precessing |
||
70 | if ( ajaxPending === false ) |
||
71 | ajaxPending = true; |
||
72 | else return; |
||
73 | |||
74 | try { |
||
75 | // --------------- Check if a submit button is found |
||
76 | if ( btnSubmit.length === 0 ) |
||
77 | throw 'Unable to find submit button'; |
||
78 | |||
79 | // --------------- Check if form method is found |
||
80 | if ( method == "" || method === null ) |
||
81 | throw 'Undefined method of form'; |
||
82 | |||
83 | // --------------- Add loader and disabled submit button |
||
84 | btnSubmit |
||
85 | .append( $( settings.icons.loading ).addClass( 'formJS-loading' ) ) |
||
86 | .attr( 'disabled' ); |
||
87 | |||
88 | btnSubmit.addClass( 'disabled' ); |
||
89 | |||
90 | // --------------- Prepare ajax setting |
||
91 | formdata = (window.FormData) ? new FormData( $this[ 0 ] ) : null; |
||
92 | data = (formdata !== null) ? formdata : $this.serialize(); |
||
93 | ajaxSettings = $.extend( settings.form.ajaxSettings, { |
||
94 | url: action, |
||
95 | type: method, |
||
96 | data: data, |
||
97 | processData: false |
||
98 | } ); |
||
99 | |||
100 | $this.trigger( 'formjs:submit', [ ajaxSettings, ajaxPending ] ); |
||
101 | |||
102 | // --------------- Send ajax request |
||
103 | $.ajax( ajaxSettings ) |
||
104 | .done( function ( feedback ) { |
||
105 | try { |
||
106 | // --------------- If no feedback found, write unexpected alert |
||
107 | if ( feedback.length === 0 ) |
||
108 | throw 'No data found on response'; |
||
109 | |||
110 | var feedbackData = $.parseJSON( feedback ); |
||
111 | var notif = ''; |
||
112 | |||
113 | $this.trigger( 'formjs:ajax-success', [ feedback ] ); |
||
114 | |||
115 | // --------------- Check feedback structure |
||
116 | $this.checkFeedbackStructure( feedbackData ); |
||
117 | |||
118 | // --------------- If url field is in feedback, prepare to redirect to it |
||
119 | if ( feedbackData.type === settings.keys.success && feedbackData.hasOwnProperty( 'url' ) ) { |
||
120 | notif = ' - ' + settings.redirection.message; |
||
121 | |||
122 | setTimeout( function () { |
||
123 | window.location.replace( feedbackData.url ); |
||
124 | }, settings.redirection.delay ); |
||
125 | } |
||
126 | |||
127 | // --------------- Make alert object with feedback |
||
128 | currentAlert.type = feedbackData.type; |
||
129 | currentAlert.title = feedbackData.data.title; |
||
130 | currentAlert.message = feedbackData.data.message + notif; |
||
131 | |||
132 | } catch ( error ) { |
||
133 | $this.logError( 'AjaxSuccessCallback', error, feedback ); |
||
134 | } |
||
135 | } ) |
||
136 | .fail( function ( error ) { |
||
137 | $this.logError( 'AjaxFailCallback', error ); |
||
138 | } ) |
||
139 | .always( function () { |
||
140 | // --------------- Call after all ajax request |
||
141 | $this.writeAlert(); |
||
142 | } ); |
||
143 | |||
144 | } catch ( error ) { |
||
145 | // --------------- Call if an error thrown before sending ajax request |
||
146 | $this.logError( 'PreSubmit', error ); |
||
147 | $this.writeAlert(); |
||
148 | } |
||
149 | }; |
||
150 | |||
151 | /** |
||
152 | * Process to sending data from the current form object |
||
153 | */ |
||
154 | $this.submit( $this.sendData ); |
||
155 | |||
156 | /** |
||
157 | * Process to sending data from on other way from the formJS plugin |
||
158 | */ |
||
159 | $this.on( 'formjs:send-form', $this.sendData ); |
||
160 | |||
161 | /** |
||
162 | * Check the structure of feedback response |
||
163 | * @param inputData |
||
164 | */ |
||
165 | $this.checkFeedbackStructure = function ( inputData ) { |
||
166 | /** |
||
167 | * feedbackStructure = { |
||
168 | type: '', |
||
169 | url: '', |
||
170 | data: { |
||
171 | title: '', |
||
172 | message: '' |
||
173 | } |
||
174 | }; |
||
175 | */ |
||
176 | |||
177 | if ( !inputData.hasOwnProperty( 'type' ) ) |
||
178 | throw 'Invalid feedback structure: "type" missing'; |
||
179 | |||
180 | if ( !inputData.hasOwnProperty( 'data' ) ) |
||
181 | throw 'Invalid feedback structure: "data" missing'; |
||
182 | |||
183 | if ( !inputData.data.hasOwnProperty( 'title' ) ) |
||
184 | throw 'Invalid feedback structure: "data.title" missing'; |
||
185 | |||
186 | if ( !inputData.data.hasOwnProperty( 'message' ) ) |
||
187 | throw 'Invalid feedback structure: "data.message" missing'; |
||
188 | |||
189 | if ( Object.keys( settings.keys ).indexOf( inputData.type ) === -1 ) |
||
190 | throw 'Invalid feedback structure: "type" wrong. Accepted values: ' + Object.keys( settings.keys ).toString(); |
||
191 | }; |
||
192 | |||
193 | /** |
||
194 | * Log and trigger error event when error are occurred during the submit processing |
||
195 | * @param place Where the error are occurred |
||
196 | * @param message Error message |
||
197 | * @param data Additional data about this error |
||
198 | */ |
||
199 | $this.logError = function ( place, message, data ) { |
||
200 | var mess = message.message || message; |
||
201 | |||
202 | console.error( '[FormJS][' + place + '] ' + mess ); |
||
203 | |||
204 | $this.trigger( 'formjs:error', [ place, mess, data ] ); |
||
205 | }; |
||
206 | |||
207 | /** |
||
208 | * Create DOM alert |
||
209 | */ |
||
210 | $this.writeAlert = function () { |
||
211 | $this.trigger( 'formjs:write-alert', [ currentAlert ] ); |
||
212 | |||
213 | if ( settings.form.enableWriteAlert === true ) { |
||
214 | // --------------- Create alert DOM element |
||
215 | var alert = $( '<div class="alert formjs-' + settings.keys[ currentAlert.type ] + '" role="alert" />' ) |
||
216 | .html( '<div class="ico">\n\ |
||
217 | ' + settings.icons[ currentAlert.type ] + '\n\ |
||
218 | </div>\n\ |
||
219 | <div class="info">\n\ |
||
220 | <h4>' + currentAlert.title + '</h4>\n\ |
||
221 | <p>' + currentAlert.message + '</p>\n\ |
||
222 | </div>' ) |
||
223 | .hide() |
||
224 | .fadeIn( 300 ); |
||
225 | |||
226 | // --------------- Add alert DOM element to the container |
||
227 | $( settings.form.alertContainer ) |
||
228 | .empty() |
||
229 | .html( alert ); |
||
230 | } |
||
231 | |||
232 | // --------------- Scroll top |
||
233 | $( 'html, body' ).animate( { |
||
234 | scrollTop: $( settings.form.alertContainer ).offset().top - 55 |
||
235 | }, 300 ); |
||
236 | |||
237 | // --------------- Enable formJS process and enabled submit button |
||
238 | var btnSubmit = $( settings.form.btnSubmit ); |
||
239 | if ( btnSubmit !== undefined && btnSubmit.length ) { |
||
240 | btnSubmit |
||
241 | .find( '.formJS-loading' ) |
||
242 | .remove(); |
||
243 | |||
244 | btnSubmit.removeClass( 'disabled' ); |
||
245 | |||
246 | ajaxPending = false; |
||
247 | } |
||
248 | |||
249 | // --------------- Print alert into developper console |
||
250 | if ( currentAlert.type === 'success' || currentAlert.type === 'info' ) |
||
251 | console.log( currentAlert.title + " - " + currentAlert.message ); |
||
252 | |||
253 | else if ( currentAlert.type === 'error' ) |
||
254 | console.error( currentAlert.title + " - " + currentAlert.message ); |
||
255 | |||
256 | else if ( currentAlert.type === 'warning' ) |
||
257 | console.warn( currentAlert.title + " - " + currentAlert.message ); |
||
258 | |||
259 | else |
||
260 | console.log( currentAlert.title + " - " + currentAlert.message ); |
||
261 | |||
262 | settings.callback( currentAlert ); |
||
263 | }; |
||
264 | |||
265 | /** |
||
266 | * Create the container if it not found |
||
267 | */ |
||
268 | $this.init = function () { |
||
269 | var container = $this.find( settings.form.alertContainer ); |
||
270 | |||
271 | if ( container.length === 0 ) { |
||
272 | var $el = $( '<div/>' ); |
||
273 | var props = settings.form.alertContainer.split( '.' ), |
||
274 | newelement = $el, |
||
275 | id = '', |
||
276 | className = ''; |
||
277 | $.each( props, function ( i, val ) { |
||
278 | if ( val.indexOf( '#' ) >= 0 ) { |
||
279 | id += val.replace( /^#/, '' ); |
||
280 | } else { |
||
281 | className += val + ' '; |
||
282 | } |
||
283 | } ); |
||
284 | |||
285 | if ( id.length ) newelement.attr( 'id', id ); |
||
286 | if ( className.length ) newelement.attr( 'class', className.trim() ); |
||
287 | |||
288 | $this.prepend( newelement ); |
||
289 | } |
||
290 | }; |
||
291 | |||
292 | $this.init(); |
||
293 | |||
294 | return $this; |
||
295 | } ); |
||
296 | }; |
||
297 | |||
299 |
This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.